package com.ruoyi.dm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.dm.domain.TrackTleConditonParam;
import com.ruoyi.dm.domain.TrackTleConditonVO;
import com.ruoyi.dm.domain.po.TrackTleConditonPO;
import com.ruoyi.dm.mapper.TrackTleConditionMapper;
import com.ruoyi.dm.service.ITrackConditionService;
import com.ruoyi.utils.TranferUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
public class TrackTleConditionServiceImpl extends ServiceImpl<TrackTleConditionMapper, TrackTleConditonPO> implements ITrackConditionService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveFile(String filePath) throws IOException {
        BufferedReader acc = new BufferedReader(new FileReader(filePath));
        //需判断文件是何种,每个文件字段不一样
        //首行是表头
        //在轨目标  OBJECT_ID,OBJECT_NAME,NORAD_CAT_ID,COUNTRY,PERIOD,INCLINATION,APOGEE,PERIGEE,RCS_SIZE,RCSVALUE,LAUNCH,COMMENT
        //陨落目标  OBJECT_ID,OBJECT_NAME,NORAD_CAT_ID,COUNTRY,PERIOD,INCLINATION,APOGEE,PERIGEE,RCS_SIZE,RCSVALUE,LAUNCH,DECAY,COMMENT
        //最新更新  NORAD_CAT_ID,OBJECT_NUMBER,CURRENT_NAME,PREVIOUS_NAME,CURRENT_INTLDES,PREVIOUS_INTLDES,CURRENT_COUNTRY,PREVIOUS_COUNTRY,CURRENT_LAUNCH,
        // PREVIOUS_LAUNCH,CURRENT_DECAY,PREVIOUS_DECAY,CHANGE_MADE
        //OBJECT_ID,OBJECT_NAME,NORAD_CAT_ID,COUNTRY,PERIOD,INCLINATION,APOGEE,PERIGEE,RCS_SIZE,RCSVALUE,LAUNCH,DECAY,COMMENT
        //"2024-108B","ELECTRON R/B","59966","US","87.39","97.48","165","125","LARGE","0","2024-06-05","2024-06-18",""
        String head = acc.readLine();
        boolean isFall = false;
        boolean isLive = false;
        boolean isUpdate = false;
        //先判断是否 更新文件  再判断 陨落和在轨
        if (head.contains("CHANGE_MADE")) {
            //最近更新
            isUpdate = true;
        }else if (head.contains("DECAY")) {
            //陨落
            isFall = true;
            //删除库内陨落的数据
            LambdaQueryWrapper<TrackTleConditonPO> qw = new LambdaQueryWrapper<>();
            qw.isNotNull(TrackTleConditonPO::getDecay);
            this.remove(qw);

        }else {
            //在轨
            isLive = true;
            //删除库内陨落的数据
            LambdaQueryWrapper<TrackTleConditonPO> qw = new LambdaQueryWrapper<>();
            qw.isNull(TrackTleConditonPO::getDecay);
            this.remove(qw);
        }
        String line = "";
        List<TrackTleConditonPO> list = new ArrayList<>(1000);
        LocalDate endDate = LocalDate.of(2024,6,20);
        while (null != (line = acc.readLine())) {
            line = line.replace("\"", "");
            String[] split = line.split(",");
            TrackTleConditonPO po = null;
            if (isFall || isLive) {
                if (isFall) {
                    po = dealWithFall(split);
                }else {
                    po = dealWithLive(split);
                }
                list.add(po);
                if (list.size() >= 1000) {
                    //批量插入
                    this.saveBatch(list);
                    list = new ArrayList<>(1000);
                }
            }else if (isUpdate) {
                po = dealWithUpdate(split);
                //逐条更新 太多了,只更新2024年6月及以后的
                LocalDate changeDate = StringUtils.hasLength(split[12])?LocalDate.parse(split[12], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")):null;
                if (changeDate.isAfter(endDate)) {
                    LambdaQueryWrapper<TrackTleConditonPO> qw = new LambdaQueryWrapper<>();
                    qw.eq(TrackTleConditonPO::getNoradCatId, po.getNoradCatId());
                    this.update(po, qw);
                }
            }
        }
        if (isFall || isLive) {
            this.saveBatch(list);
        }
    }

    private TrackTleConditonPO dealWithUpdate(String[] split) {
        //NORAD_CAT_ID,
        // OBJECT_NUMBER,
        // CURRENT_NAME,
        // PREVIOUS_NAME,
        // CURRENT_INTLDES,
        // PREVIOUS_INTLDES,
        // CURRENT_COUNTRY,
        // PREVIOUS_COUNTRY,
        // CURRENT_LAUNCH,
        // PREVIOUS_LAUNCH,
        // CURRENT_DECAY,
        // PREVIOUS_DECAY,
        // CHANGE_MADE
        TrackTleConditonPO po = new TrackTleConditonPO();
        po.setObjectName(split[2]);
        po.setCountry(split[6]);
        LocalDate launch = StringUtils.hasLength(split[8])?LocalDate.parse(split[8], DateTimeFormatter.ISO_LOCAL_DATE):null;
        po.setLaunch(launch);
        LocalDate decay = StringUtils.hasLength(split[10])?LocalDate.parse(split[10], DateTimeFormatter.ISO_LOCAL_DATE):null;
        po.setDecay(decay);
        po.setNoradCatId(split[0]);
        return po;
    }

    private TrackTleConditonPO dealWithLive(String[] split) {
        TrackTleConditonPO po = new TrackTleConditonPO();
        po.setObjectId(split[0]);
        po.setObjectName(split[1]);
        po.setNoradCatId(split[2]);
        po.setCountry(split[3]);
        po.setPeriod(StringUtils.hasLength(split[4])?Double.valueOf(split[4]):null);
        po.setInclination(StringUtils.hasLength(split[5])?Double.valueOf(split[5]):null);
        po.setApogee(StringUtils.hasLength(split[6])?Double.valueOf(split[6]):null);
        po.setPerigee(StringUtils.hasLength(split[7])?Double.valueOf(split[7]):null);
        po.setRcsSize(split[8]);
        po.setRcsvalue(split[9]);
        LocalDate launch = StringUtils.hasLength(split[10])?LocalDate.parse(split[10], DateTimeFormatter.ofPattern("yyyy/M/d")):null;
        po.setLaunch(launch);
        return po;
    }

    private TrackTleConditonPO dealWithFall(String[] split) {
        TrackTleConditonPO po = new TrackTleConditonPO();
        po.setObjectId(split[0]);
        po.setObjectName(split[1]);
        po.setNoradCatId(split[2]);
        po.setCountry(split[3]);
        po.setPeriod(StringUtils.hasLength(split[4])?Double.valueOf(split[4]):null);
        po.setInclination(StringUtils.hasLength(split[5])?Double.valueOf(split[5]):null);
        po.setApogee(StringUtils.hasLength(split[6])?Double.valueOf(split[6]):null);
        po.setPerigee(StringUtils.hasLength(split[7])?Double.valueOf(split[7]):null);
        po.setRcsSize(split[8]);
        po.setRcsvalue(split[9]);
        LocalDate launch = StringUtils.hasLength(split[10])?LocalDate.parse(split[10], DateTimeFormatter.ISO_LOCAL_DATE):null;
        po.setLaunch(launch);
        LocalDate decay = StringUtils.hasLength(split[11])?LocalDate.parse(split[11], DateTimeFormatter.ISO_LOCAL_DATE):null;
        po.setDecay(decay);
        return po;
    }

    @Override
    public IPage<TrackTleConditonVO> query(TrackTleConditonParam queryParam) {
        QueryWrapper<TrackTleConditonPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.hasLength(queryParam.getObjectId()),"NORAD_CAT_ID",queryParam.getObjectId());
        queryWrapper.like(StringUtils.hasLength(queryParam.getObjectName()),"OBJECT_NAME",queryParam.getObjectName());
        queryWrapper.eq(null != queryParam.getPeriod(),"PERIOD",queryParam.getPeriod());
        queryWrapper.eq(null != queryParam.getInclination(),"INCLINATION",queryParam.getInclination());
        queryWrapper.eq(null != queryParam.getApogee(), "APOGEE",queryParam.getApogee());
        queryWrapper.eq(null != queryParam.getPerigee(), "PERIGEE",queryParam.getPerigee());
        //将 orderby 字段映射一下
        String realColumn = mapOrderBy(queryParam.getOrderby());
        queryWrapper.orderBy(StringUtils.hasLength(realColumn),"asc".equals(queryParam.getSort()) ,realColumn);
        queryWrapper.between(null != queryParam.getLaunchStart() && null!= queryParam.getLaunchEnd(),"LAUNCH",queryParam.getLaunchStart(),queryParam.getLaunchEnd());
        queryWrapper.between(null != queryParam.getDecayStart() && null!= queryParam.getDecayEnd(),"DECAY",queryParam.getDecayStart(),queryParam.getDecayEnd());
        IPage page = this.page(queryParam.page(), queryWrapper);
        List<TrackTleConditonVO> objects = new ArrayList<>();
        for (Object airCollectRecordPO : page.getRecords()) {
            TrackTleConditonPO po = (TrackTleConditonPO) airCollectRecordPO;
            TrackTleConditonVO vo = TranferUtils.tranferTleConditionPO(po);
            objects.add(vo);
        }
        page.setRecords(objects);
        return page;
    }

    //将页面穿的 orderby 字段映射
    private String mapOrderBy(String orderby) {
        if (!StringUtils.hasLength(orderby)) {
            return null;
        }
        String s = com.ruoyi.common.utils.StringUtils.toUnderScoreCase(orderby);
        return s;
    }
}
